﻿#include "DataMeasurementDialog.h"
#include "ui_DataMeasurement.h"
#include <QtCore/qmath.h>
#include "linechart.h"
#include "CheckPosition.h"
#include "b3mainwindow.h"
#include "StageControl.h"

#include <Windows.h>


DataMeasurementDialog::DataMeasurementDialog(QWidget *parent, B3MainWindow *win, CameraImage *cameraImage) :
    QDialog(parent),
    ui(new Ui::DataMeasurement),
    m_autoFocusSemaphore(0)
{
    ui->setupUi(this);
    setWindowTitle(QString::fromLocal8Bit("准备测量"));
    m_sqlite = new Sqlite;
    m_index = 0;
    m_index_CF = 0;
    m_index_TFT = 0;
    m_state = STATE_IDLE;

    m_cameraImage = cameraImage;
    m_win = win;
    m_stageControl = NULL;
    connect(m_win, SIGNAL(autoPanelMeasure()), this, SLOT(autoPanelMeasure()));
    connect(ui->pushButton_StartMeasurement_CF, SIGNAL(clicked()), this, SLOT(StartMeasurement_CF()));
    connect(ui->pushButton_StartMeasurement_TFT, SIGNAL(clicked()), this, SLOT(StartMeasurement_TFT()));
    connect(ui->pushButton_Save, SIGNAL(clicked()), this, SLOT(Save()));
    connect(ui->pushButton_Next, SIGNAL(clicked()), this, SLOT(NewPanel()));
    connect(m_win, SIGNAL(autoFocusFinish()), this, SLOT(autoFocusFinished()));
    NewPanel();
    isAutoFocus = false;

//    m_focusMeasure.setZoomFactor(10);
}

DataMeasurementDialog::~DataMeasurementDialog()
{
    m_stageControl->stop();
    if(m_sqlite != nullptr)
    {
        delete m_sqlite;
        m_sqlite = nullptr;
    }
    delete ui;
}

void DataMeasurementDialog::setMainWindow(B3MainWindow *win)
{
    m_win = win;
}

void DataMeasurementDialog::setStageControl(StageControl *stageControl)
{
    m_stageControl = stageControl;
    connect(m_stageControl, SIGNAL(moveToPos_achieve()), this, SLOT(moveToPos_achieve()));
    connect(m_stageControl, SIGNAL(zMoveFinish()), this, SLOT(moveToPos_achieve()));
    connect(m_stageControl, SIGNAL(zMoveFinish()), this, SLOT(zMoveFinished()));

    if(m_stageControl)m_stageControl->xyMoveToPos(50, 50, 100);
}

void DataMeasurementDialog::setData(QString dataBaseName, QString sqlDirPath)
{
    m_dataBaseName = dataBaseName;
    m_sqlDirPath = sqlDirPath;

    QString sqlPath = sqlDirPath + "/" + dataBaseName + ".db";
    m_sqlite->setSqlData(sqlPath, dataBaseName);

    readSpecData();
    addChart2TabWidget();
    //ui->lineEdit_Cpk->clear();

    ui->plainTextEdit_log->appendPlainText("open datavase " + dataBaseName);

}

void DataMeasurementDialog::readSpecData()
{
    measureSpecInfoList.clear();
    measureSpecInfoList_CF.clear();
    measureSpecInfoList_TFT.clear();
    if( m_sqlite->readMeasureSpec(measureSpecInfoList))
    {
        QList<MeasureSpecInfo>::iterator i;
        for(i = measureSpecInfoList.begin(); i != measureSpecInfoList.end(); ++i)
        {
            if(i->side)
            {
                measureSpecInfoList_TFT << *i;
            }
            else
            {
                measureSpecInfoList_CF << *i;
            }
        }
        ui->groupBox->installEventFilter(this);
        setUiControlValue(m_index);
    }
    measureSpecInfoList.clear();
    measureSpecInfoList << measureSpecInfoList_CF;
    measureSpecInfoList << measureSpecInfoList_TFT;
}

void DataMeasurementDialog::setUiControlValue(int index)
{
    ui->lineEdit_SpecNumber->setText(QString::number(measureSpecInfoList[index].MeasureID));
    ui->lineEdit_startX->setText(QString::number(measureSpecInfoList[index].startX));
    ui->lineEdit_startY->setText(QString::number(measureSpecInfoList[index].startY));
    ui->lineEdit_startZ->setText(QString::number(measureSpecInfoList[index].startZ));
    ui->lineEdit_endX->setText(QString::number(measureSpecInfoList[index].endX));
    ui->lineEdit_endY->setText(QString::number(measureSpecInfoList[index].endY));
    ui->lineEdit_endZ->setText(QString::number(measureSpecInfoList[index].endZ));
    ui->lineEdit_CL->setText(QString::number(measureSpecInfoList[index].CL));
    ui->lineEdit_UCL->setText(QString::number(measureSpecInfoList[index].UCL));
    ui->lineEdit_LCL->setText(QString::number(measureSpecInfoList[index].LCL));
    ui->lineEdit_USL->setText(QString::number(measureSpecInfoList[index].USL));
    ui->lineEdit_LSL->setText(QString::number(measureSpecInfoList[index].LSL));
}

void DataMeasurementDialog::addChart2TabWidget(int showDataNumber)
{
    QList<QString> dateTime;
    QList<MeasureSpecInfo> info;
    QList<QStringList> data;
    m_sqlite->readMeasureSpec(info);
    m_sqlite->readMeasureData(dateTime, data, info.size(), showDataNumber);

    LineChart line;
    QList<double> specsList;
    QList<double> datalist;

    ui->tabWidget->clear();

    for(int i = 0; i < info.size(); i++)
    {
        specsList.append(info[i].CL);
        specsList.append(info[i].UCL);
        specsList.append(info[i].LCL);
        specsList.append(info[i].USL);
        specsList.append(info[i].LSL);

        for(int n = 0; n < data.size(); n++)
        {
            datalist.append(data[n].at(i).toDouble());
            if(n < CpkLength)
            {
                CpkData[n] = data[n].at(i).toDouble();
            }
        }
        double Cpk;
        if(data.size() > 0)
        {
            double mean = gsl_stats_mean(CpkData, 1, MIN(datalist.size(), CpkLength));
            double sigma = gsl_stats_sd(CpkData, 1,  MIN(datalist.size(), CpkLength));//standard deviation
            Cpk = MIN(fabs(mean - info[i].USL), fabs(mean - info[i].LSL)) / (3 * sigma);
//            qDebug() << "Cpk = " << Cpk;
            //ui->lineEdit_Cpk->setText(QString::number(Cpk));
            if(data[0].at(i).toDouble() > info[i].UCL)
            {
                QMessageBox::warning(NULL, QString::fromLocal8Bit("警告"), QString::fromLocal8Bit("测点%1最新测量值大于管控值！").arg(i+1));
            }
            if(data[0].at(i).toDouble() < info[i].LCL)
            {
                QMessageBox::warning(NULL, QString::fromLocal8Bit("警告"), QString::fromLocal8Bit("测点%1最新测量值小于管控值！").arg(i+1));
            }
            if(Cpk <= 1.33 && data.size() >= 30)
            {
                QMessageBox::warning(NULL, QString::fromLocal8Bit("警告"), QString::fromLocal8Bit("测点%1Cpk值小于等于1.33！").arg(i+1));
            }
            if(data.size() >= 9)
            {
                bool allBig = true;
                bool allSmall = true;
                for(int k = 0; k < 9; k++)
                {
                    if(data[k].at(i).toDouble() >= info[i].CL) allSmall = false;
                    if(data[k].at(i).toDouble() <= info[i].CL) allBig = false;
                }
                //if(allBig)QMessageBox::warning(NULL, QString::fromLocal8Bit("警告"), QString::fromLocal8Bit("测点%1最新9个测量值全部大于中心值！").arg(i+1));
                //if(allSmall)QMessageBox::warning(NULL, QString::fromLocal8Bit("警告"), QString::fromLocal8Bit("测点%1最新9个测量值全部小于中心值！").arg(i+1));
            }
        }
        line.tabWidgetAddChart(ui->tabWidget, datalist, specsList, dateTime, datalist.size(), QString::fromLocal8Bit("测点%1(Cpk=%2)").arg(i+1).arg(QString::number(Cpk, 'f', 2)));
        specsList.clear();
        datalist.clear();
    }
}

bool DataMeasurementDialog::eventFilter(QObject *object, QEvent *event)
{
    if(object == ui->groupBox && event->type() == QEvent::Paint)
    {
        paintLine();
    }
    return QWidget::eventFilter(object,event);
}

void DataMeasurementDialog::paintLine()
{
    QPainter painter(ui->groupBox);
    painter.setRenderHint(QPainter::Antialiasing, true);
    QFont font = painter.font();
    font.setPixelSize(12);
    painter.setFont(font);
    int left_CF = INT_MAX;
    int top_CF = INT_MAX;
    int right_CF = 0;
    int bottom_CF = 0;
    int left_TFT = INT_MAX;
    int top_TFT = INT_MAX;
    int right_TFT = 0;
    int bottom_TFT = 0;

    for(int i = 0; i < measureSpecInfoList.size(); i++)
    {
        float startX = measureSpecInfoList[i].startX;
        float startY = measureSpecInfoList[i].startY;
        float endX = measureSpecInfoList[i].endX;
        float endY = measureSpecInfoList[i].endY;

        if(measureSpecInfoList[i].side)//TFT
        {
            painter.setPen(QPen(Qt::blue, 2, Qt::DashLine, Qt::RoundCap));
            if(startX < endX)
            {
                if(startX < left_TFT) left_TFT = startX;
                if(endX > right_TFT) right_TFT = endX;
            }
            else
            {
                if(endX < left_TFT) left_TFT = endX;
                if(startX > right_TFT) right_TFT = startX;
            }
            if(startY < endY)
            {
                if(startY < top_TFT) top_TFT = startY;
                if(endY > bottom_TFT) bottom_TFT = endY;
            }
            else
            {
                if(endY < top_TFT) top_TFT = endY;
                if(startY > bottom_TFT) bottom_TFT = startY;
            }
        }
        else
        {
            painter.setPen(QPen(Qt::red, 2, Qt::DashLine, Qt::RoundCap));
            if(startX < endX)
            {
                if(startX < left_CF) left_CF = startX;
                if(endX > right_CF) right_CF = endX;
            }
            else
            {
                if(endX < left_CF) left_CF = endX;
                if(startX > right_CF) right_CF = startX;
            }
            if(startY < endY)
            {
                if(startY < top_CF) top_CF = startY;
                if(endY > bottom_CF) bottom_CF = endY;
            }
            else
            {
                if(endY < top_CF) top_CF = endY;
                if(startY > bottom_CF) bottom_CF = startY;
            }
        }

        painter.drawLine(startX,startY,endX,endY);

        painter.drawText((startX+endX)/2+5, (startY+endY)/2+15, QString::fromLocal8Bit("测点%1 长度%2").arg(measureSpecInfoList[i].MeasureID).arg(measureSpecInfoList[i].CL));

        float x1 = startX;         //起点
        float y1 = startY;
        float x2 = endX;           //终点
        float y2 = endY;
        float l = 15.0;            //箭头的长度
        float a = 0.3;             //箭头与线段角度

        float x3 = x2 - l * cos(atan2((y2 - y1) , (x2 - x1)) - a);
        float y3 = y2 - l * sin(atan2((y2 - y1) , (x2 - x1)) - a);
        float x4 = x2 - l * sin(atan2((x2 - x1) , (y2 - y1)) - a);
        float y4 = y2 - l * cos(atan2((x2 - x1) , (y2 - y1)) - a);
        painter.drawLine(x2,y2,x3,y3);
        painter.drawLine(x2,y2,x4,y4);
    }
    font.setPixelSize(20);
    painter.setFont(font);
    painter.setPen(QPen(Qt::red, 1, Qt::SolidLine, Qt::RoundCap));
    painter.drawRect(left_CF, top_CF, right_CF - left_CF, bottom_CF - top_CF);
    painter.setPen(QPen(Qt::blue, 1, Qt::SolidLine, Qt::RoundCap));
    painter.drawRect(left_TFT, top_TFT, right_TFT - left_TFT, bottom_TFT - top_TFT);
    painter.setPen(QPen(Qt::black, 2, Qt::SolidLine, Qt::RoundCap));
    painter.drawText(40, 40, QString::fromLocal8Bit("红色为CF面，蓝色为TFT面。"));
}

void DataMeasurementDialog::NewPanel()
{
    isAutoFocus = false;
    m_index = 0;
    m_index_CF = 0;
    m_index_TFT = 0;
    m_state = STATE_IDLE;
    m_measureData.clear();
    m_measureData_CF.clear();
    m_measureData_TFT.clear();
    ui->lineEdit_Length->setText("");
    ui->pushButton_StartMeasurement_CF->setEnabled(true);
    ui->pushButton_StartMeasurement_TFT->setEnabled(false);
    ui->pushButton_Save->setEnabled(false);
    ui->pushButton_Next->setEnabled(false);
    //ui->lineEdit_Cpk->clear();
    //清除表格
    int rowCount = ui->tableWidget_Data->rowCount();
    for(int r = rowCount-1 ; r >=0 ; r--)
    {
        ui->tableWidget_Data->removeRow(r);
    }
    ui->tableWidget_Data->horizontalHeader()->setStretchLastSection(true);               //设置最后一行自动填满
    ui->tableWidget_Data->setEditTriggers(QAbstractItemView::NoEditTriggers);            //设置不能编辑
}

void DataMeasurementDialog::autoPanelMeasure()
{
    if(ui->pushButton_StartMeasurement_CF->isEnabled())
    {
        StartMeasurement_CF();
        return;
    }
    if(ui->pushButton_StartMeasurement_TFT->isEnabled())
    {
        StartMeasurement_TFT();
        return;
    }
    if(ui->pushButton_Next->isEnabled())
    {
        NewPanel();
        Sleep(500);
        return;
    }
}

void DataMeasurementDialog::StartMeasurement_CF()
{
    ui->plainTextEdit_log->appendPlainText("StartMeasurement_CF");

    m_win->setCamera(true);
    ui->tabWidget_pic->clear();
    if(m_state != STATE_IDLE)
    {
        return;
    }
    m_measureData_CF.clear();
    m_index_CF = 0;
    m_index = m_index_CF + m_index_TFT;
    setUiControlValue(m_index);
    ui->pushButton_StartMeasurement_CF->setEnabled(false);
    if(m_index_CF < measureSpecInfoList_CF.size())
    {
        m_state = STATE_MOVE2START_CF;

        move2start();
    }
    else
    {
        //QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("CF面无测点！"));
        ui->pushButton_StartMeasurement_TFT->setEnabled(true);
    }
}

void DataMeasurementDialog::StartMeasurement_TFT()
{
    ui->plainTextEdit_log->appendPlainText("StartMeasurement_TFT");
    m_win->setCamera(true);
    if(m_state != STATE_IDLE)
    {
        return;
    }
    m_measureData_TFT.clear();
    m_index_TFT = 0;
    m_index = m_index_CF + m_index_TFT;

    ui->pushButton_StartMeasurement_TFT->setEnabled(false);
    if(m_index_TFT < measureSpecInfoList_TFT.size())
    {
        setUiControlValue(m_index);
        m_state = STATE_MOVE2START_TFT;
        move2start();
    }
    else
    {
        QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("TFT面无测点！"));
        m_state = STATE_IDLE;
        ui->pushButton_StartMeasurement_CF->setEnabled(false);
        ui->pushButton_StartMeasurement_TFT->setEnabled(false);
        ui->pushButton_Save->setEnabled(true);
        ui->pushButton_Next->setEnabled(true);
        QMessageBox::information(NULL, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("测量完毕，请注意手动保存！"));
    }
}

void DataMeasurementDialog::moveToPos_achieve()
{
    //qDebug() << "m_state:" << m_state;
    switch (m_state)
    {
    case STATE_IDLE:
        break;
    case STATE_MOVE2START_CF:
        Sleep(wiatTime);
        if(!autoFocus2())break;
        ui->plainTextEdit_log->appendPlainText(QString("autoFocus acheieve"));
        m_currentStartLine = lineMeasure(m_bestImage);
        ui->plainTextEdit_log->appendPlainText(QString("START_CF lineMeasure:%1").arg(m_currentStartLine));
        while(m_currentStartLine < 0)
        {
            if(QMessageBox::question(this, u8"询问", u8"没有检测到合理的直线，点击🆗进行手动对焦。") == QMessageBox::Yes)
            {
                if(manualFocus(m_currentStartLine))
                {
//                    m_currentStartLine = lineMeasure(m_win->getImage());
                }
                else
                {
                    NewPanel();
                    m_stageControl->xyMoveToPos(50, 50, 100);
                    return;
                }
            }
            else
            {
                NewPanel();
                m_stageControl->xyMoveToPos(50, 50, 100);
                return;
            }
            //QMessageBox::about(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("没有检测到合理的直线，请手动对焦。"));
        }
        m_state = STATE_MOVE2END_CF;
        move2end();
        break;
    case STATE_MOVE2END_CF:
        Sleep(wiatTime);
        if(!autoFocus2())break;
        ui->plainTextEdit_log->appendPlainText(QString("autoFocus acheieve"));
        m_currentEndLine = lineMeasure(m_bestImage);
        ui->plainTextEdit_log->appendPlainText(QString("END_CF lineMeasure:%1").arg(m_currentStartLine));
        while(m_currentEndLine < 0)
        {
            if(QMessageBox::question(this, u8"询问", u8"没有检测到合理的直线，点击ok进行手动对焦。") == QMessageBox::Yes)
            {
                if(manualFocus(m_currentEndLine))
                {
//                    m_currentEndLine = lineMeasure(m_win->getImage());
                }
                else
                {
                    NewPanel();
                    m_stageControl->xyMoveToPos(50, 50, 100);
                    return;
                }
            }
            else
            {
                NewPanel();
                m_stageControl->xyMoveToPos(50, 50, 100);
                return;
            }
            //QMessageBox::about(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("没有检测到合理的直线，请手动对焦。"));
        }
        measure();
        m_index_CF++;
        m_index = m_index_CF + m_index_TFT;
        if(m_index_CF < measureSpecInfoList_CF.size() )
        {
            setUiControlValue(m_index);
            m_state = STATE_MOVE2START_CF;
            move2start();
        }
        else
        {
            m_state = STATE_IDLE;
            ui->pushButton_StartMeasurement_CF->setEnabled(false);
            ui->pushButton_StartMeasurement_TFT->setEnabled(true);
            m_stageControl->xyMoveToPos(50, 50, 100);
        }
        break;
    case STATE_MOVE2START_TFT:
        Sleep(wiatTime);
        if(!autoFocus2())break;
        ui->plainTextEdit_log->appendPlainText(QString("autoFocus acheieve"));
        m_currentStartLine = lineMeasure(m_bestImage);
        ui->plainTextEdit_log->appendPlainText(QString("START_TFT lineMeasure:%1").arg(m_currentStartLine));
        while(m_currentStartLine < 0)
        {
            if(QMessageBox::question(this, u8"询问", u8"没有检测到合理的直线，点击ok进行手动对焦。") == QMessageBox::Yes)
            {
                if(manualFocus(m_currentStartLine))
                {
                    //m_currentStartLine = lineMeasure(m_win->getImage());
                }
                else
                {
                    NewPanel();
                    m_stageControl->xyMoveToPos(50, 50, 100);
                    return;
                }
            }
            else
            {
                NewPanel();
                m_stageControl->xyMoveToPos(50, 50, 100);
                return;
            }
            //QMessageBox::about(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("没有检测到合理的直线，请手动对焦。"));
        }
        m_state = STATE_MOVE2END_TFT;
        move2end();
        break;
    case STATE_MOVE2END_TFT:
        Sleep(wiatTime);
        if(!autoFocus2())break;
        ui->plainTextEdit_log->appendPlainText(QString("autoFocus acheieve"));
        m_currentEndLine = lineMeasure(m_bestImage);
        ui->plainTextEdit_log->appendPlainText(QString("END_TFT lineMeasure:%1").arg(m_currentStartLine));
        while(m_currentEndLine < 0)
        {
            if(QMessageBox::question(this, u8"询问", u8"没有检测到合理的直线，点击OK进行手动对焦。") == QMessageBox::Yes)
            {
                if(manualFocus(m_currentEndLine))
                {
                    //m_currentEndLine = lineMeasure(m_win->getImage());
                }
                else
                {
                    NewPanel();
                    m_stageControl->xyMoveToPos(50, 50, 100);
                    return;
                }
            }
            else
            {
                NewPanel();
                m_stageControl->xyMoveToPos(50, 50, 100);
                return;
            }
            //QMessageBox::about(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("没有检测到合理的直线，请手动对焦。"));
        }
        measure();
        m_index_TFT++;
        m_index = m_index_CF + m_index_TFT;
        if(m_index_TFT < measureSpecInfoList_TFT.size() )
        {
            setUiControlValue(m_index);
            m_state = STATE_MOVE2START_TFT;
            move2start();
        }
        else
        {
            m_state = STATE_IDLE;
            ui->pushButton_StartMeasurement_CF->setEnabled(false);
            ui->pushButton_StartMeasurement_TFT->setEnabled(false);
            ui->pushButton_Save->setEnabled(true);
            ui->pushButton_Next->setEnabled(true);
            m_stageControl->xyMoveToPos(50, 50, 100);
            QMessageBox::information(NULL, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("测量完毕，请注意手动保存！"));
        }
        break;
    default:
        break;
    }
}

bool DataMeasurementDialog::autoFocus()
{
    //return true;
    //qDebug() << "isAutoFocus:" << isAutoFocus;
    double pos_mm[4];
    m_win->getEncodePosition(pos_mm);
    //qDebug() << "zList.size() = " << zList.size();
    if(isAutoFocus)
    {
        if(zList.size() > 0)
        {
            //QImage image = m_win->getImage().copy(QRect(roi.left() + 0.25 * roi.width(), roi.top() + 0.25 * roi.height(), 0.5 * roi.width(), 0.5 * roi.height()));
            QImage img = m_win->getImage();
//            int roiwidth = 200 / m_currentScale;
//            roi.setRect(0.5 * img.width() - 0.5 * roiwidth, 0.5 * img.height() - 0.5 * roiwidth, 0.6 * img.width() , 0.6 * img.height());
            roi.setRect(0.1 * img.width(), 0.1 * img.height(), 0.8 * img.width() , 0.8 * img.height());
            QImage image = m_win->getImage().copy(roi);
            //ui->label_pic->setPixmap(QPixmap::fromImage(image).scaled(ui->label_pic->size()));
            cv::Mat mat = m_focusMeasure.preprocess(image);
            double score = m_focusMeasure.measure(mat);
            //qDebug() << "autoFocus z = " << zList[0] << ", score = " << score;
            if(score > best_score)
            {
                best_score = score ;
                z_best = zList[0];
                //m_currentEndLine = lineMeasure(m_win->getImage());
                m_bestImage = image.copy();
            }
            zList.removeAt(0);
            if(zList.size() == 0)
            {
                qDebug() << "z_best z = " << z_best ;
                m_stageControl->moveToPos(pos_mm[0], pos_mm[1], z_best);
            }
            else
            {
                m_stageControl->moveToPos(pos_mm[0], pos_mm[1], zList[0]);
            }
            return false;
        }
        else
        {
            isAutoFocus = false;
            return true;
        }
    }
    else
    {
        isAutoFocus = true;
        zList.clear();
        double zStep = 0.02;
        switch(m_currentLens)
        {
        case 0:
            zStep = 0.04;
            break;
        case 1:
            zStep = 0.02;
            break;
        case 2:
            zStep = 0.01;
            break;
        case 3:
            zStep = 0.004;
            break;
        case 4:
            zStep = 0.002;
            break;
        case 5:
            zStep = 0;
            break;
        }
        zList << pos_mm[2] - zStep * 4;
        zList << pos_mm[2] - zStep * 3;
        zList << pos_mm[2] - zStep * 2;
        zList << pos_mm[2] - zStep;
        zList << pos_mm[2];
        zList << pos_mm[2] + zStep;
        zList << pos_mm[2] + zStep * 2;
        zList << pos_mm[2] + zStep * 3;
        zList << pos_mm[2] + zStep * 4;
        best_score = -1;
        z_best = zList[0];
        m_stageControl->moveToPos(pos_mm[0], pos_mm[1], zList[0]);
        return false;
    }
}

double autoSpeed = 5;

bool DataMeasurementDialog::autoFocus2()
{
    double pos_mm[4];
    m_win->getEncodePosition(pos_mm);
    if(isAutoFocus)
    {
        zList.removeAt(0);
        if(zList.size() > 0)
        {
            m_stageControl->moveToPos(pos_mm[0], pos_mm[1], zList[0], autoSpeed * 10);
            return false;
        }
        else
        {
            m_cameraImage->stopFocus();
//            qDebug() << "stopFocus";
            m_bestImage = m_cameraImage->getBestImage().copy();
//            qDebug() << "getBestImage";
            isAutoFocus = false;
            return true;
        }
    }
    else
    {
        isAutoFocus = true;
        zList.clear();
        double zStep = 0.02;
        switch(m_currentLens)
        {
        case 0:
            zStep = 0.2;
            break;
        case 1:
            zStep = 0.1;
            break;
        case 2:
            zStep = 0.05;
            break;
        case 3:
            zStep = 0.025;
            break;
        case 4:
            zStep = 0.01;
            break;
        case 5:
            zStep = 0.1;
            break;
        }
        zList << pos_mm[2] - zStep;
        zList << pos_mm[2] + zStep;
        autoSpeed = zStep * 2;
        z_best = zList[0];
        m_cameraImage->startFocus();
        m_stageControl->moveToPos(pos_mm[0], pos_mm[1], z_best);

        ui->plainTextEdit_log->appendPlainText(QString(u8"autoFocus,zRange=±%1mm(%2--%3),speed =%4mm/s").arg(zStep).arg(zList[0]).arg(zList[1]).arg(autoSpeed));
        return false;
    }
}

bool DataMeasurementDialog::manualFocus(double &result)
{
    Dialog_ManualFocus m_manualFocus;
    connect(m_win, SIGNAL(RGB24ImageChanged(const uint8_t*,QSize)), &m_manualFocus, SLOT(updateImage(const uint8_t*,QSize)));
    connect(&m_manualFocus, SIGNAL(moveUp()), m_stageControl, SLOT(moveUp()));
    connect(&m_manualFocus, SIGNAL(moveDown()), m_stageControl, SLOT(moveDown()));
    connect(&m_manualFocus, SIGNAL(stop()), m_stageControl, SLOT(stopZ()));
    connect(&m_manualFocus, SIGNAL(changeSpeed(double)), m_stageControl, SLOT(setZSpeed(double)));
    int r = m_manualFocus.exec();//将Dialog 设置为模态对话框，程序运行到这一行就会阻塞了
    if(r == QDialog::Rejected) return false;

    int ret = m_manualFocus.getResult() * 2;
    result = m_currentScale * ret / 1000;

    qDebug() << "draw line" << ret;
    QImage image = m_win->getImage();
    cv::Mat m_cvimage = QImage2cvMat(image).clone();

    if(m_measurementTypt == LEFT || m_measurementTypt == RIGHT)
    {
        qDebug() << "m_cvimage.rows" << m_cvimage.rows;
        qDebug() << "m_cvimage.cols" << m_cvimage.cols;
        cv::line( m_cvimage, cv::Point(ret, 0), cv::Point(ret, m_cvimage.rows), cv::Scalar(0,255,0), 5);
    }
    else
    {
        qDebug() << "m_cvimage.cols" << m_cvimage.cols;
        qDebug() << "m_cvimage.rows" << m_cvimage.rows;
        cv::line( m_cvimage, cv::Point(0, ret), cv::Point(m_cvimage.cols, ret), cv::Scalar(0,255,0), 5);
    }

    qDebug() << "add tab";
    QLabel* tab = new QLabel(ui->tabWidget_pic);
    ui->tabWidget_pic->addTab(tab, QString::fromLocal8Bit("%1").arg(m_index + 1)); //将图表加入tabWidget当中，并设置标题
    QVBoxLayout* verticalLayout = new QVBoxLayout(tab);
    verticalLayout->addWidget(tab);
    tab->setGeometry(0, 0, 390, 280);
    tab->setPixmap(QPixmap::fromImage(cvMat2QImage(m_cvimage)).scaled(tab->size()));
    ui->tabWidget_pic->setCurrentWidget(tab);
    return true;
}

void DataMeasurementDialog::move2start()
{
    ui->plainTextEdit_log->appendPlainText("move2start");

    m_currentX = measureSpecInfoList[m_index].startX;
    m_currentY = measureSpecInfoList[m_index].startY;
    m_currentZ = measureSpecInfoList[m_index].startZ;
    m_currentScale = measureSpecInfoList[m_index].startScale;
    m_currentLens = measureSpecInfoList[m_index].startLens;
    m_currentIntensity_top = measureSpecInfoList[m_index].startIntensity_top;
    m_currentIntensity_bottom = measureSpecInfoList[m_index].startIntensity_bottom;
    m_currentExpoureTime = measureSpecInfoList[m_index].startExpoureTime;

    //    qDebug() << "m_currentX:" << m_currentX;
    //    qDebug() << "m_currentY:" << m_currentY;
    //    qDebug() << "m_currentZ:" << m_currentZ;
    //    qDebug() << "m_currentScale:" << m_currentScale;
    //    qDebug() << "m_currentLens:" << m_currentLens;
    //    qDebug() << "m_currentIntensity_top:" << m_currentIntensity_top;
    //    qDebug() << "m_currentIntensity_bottom:" << m_currentIntensity_bottom;
    //    qDebug() << "m_currentExpoureTime:" << m_currentExpoureTime;

    ui->plainTextEdit_log->appendPlainText(QString("setLens:%1").arg(m_currentLens));
    m_win->setLens(m_currentLens);
    ui->plainTextEdit_log->appendPlainText(QString("setIntensity_top:%1").arg(m_currentIntensity_top));
    m_win->setIntensity_top(m_currentIntensity_top);
    ui->plainTextEdit_log->appendPlainText(QString("setIntensity_bottom:%1").arg(m_currentIntensity_bottom));
    m_win->setIntensity_bottom(m_currentIntensity_bottom);
    ui->plainTextEdit_log->appendPlainText(QString("setExpoureTime:%1").arg(m_currentExpoureTime));
    m_win->setExpoureTime(m_currentExpoureTime);
    ui->plainTextEdit_log->appendPlainText(QString("moveToPos:(%1,%2,%3) by seppd = %4mm/s").arg(m_currentX).arg(m_currentY).arg(m_currentZ).arg(100));
    m_stageControl->moveToPos(m_currentX, m_currentY, m_currentZ, 100);
}

void DataMeasurementDialog::move2end()
{
    ui->plainTextEdit_log->appendPlainText("move2end");
    m_currentX = measureSpecInfoList[m_index].endX;
    m_currentY = measureSpecInfoList[m_index].endY;
    m_currentZ = measureSpecInfoList[m_index].endZ;
    m_currentScale = measureSpecInfoList[m_index].endScale;
    m_currentLens = measureSpecInfoList[m_index].endLens;
    m_currentIntensity_top = measureSpecInfoList[m_index].endIntensity_top;
    m_currentIntensity_bottom = measureSpecInfoList[m_index].endIntensity_bottom;
    m_currentExpoureTime = measureSpecInfoList[m_index].endExpoureTime;

    //    qDebug() << "m_currentX:" << m_currentX;
    //    qDebug() << "m_currentY:" << m_currentY;
    //    qDebug() << "m_currentZ:" << m_currentZ;
    //    qDebug() << "m_currentScale:" << m_currentScale;
    //    qDebug() << "m_currentLens:" << m_currentLens;
    //    qDebug() << "m_currentIntensity_top:" << m_currentIntensity_top;
    //    qDebug() << "m_currentIntensity_bottom:" << m_currentIntensity_bottom;
    //    qDebug() << "m_currentExpoureTime:" << m_currentExpoureTime;

    ui->plainTextEdit_log->appendPlainText(QString("setLens:%1").arg(m_currentLens));
    m_win->setLens(m_currentLens);
    ui->plainTextEdit_log->appendPlainText(QString("setIntensity_top:%1").arg(m_currentIntensity_top));
    m_win->setIntensity_top(m_currentIntensity_top);
    ui->plainTextEdit_log->appendPlainText(QString("setIntensity_bottom:%1").arg(m_currentIntensity_bottom));
    m_win->setIntensity_bottom(m_currentIntensity_bottom);
    ui->plainTextEdit_log->appendPlainText(QString("setExpoureTime:%1").arg(m_currentExpoureTime));
    m_win->setExpoureTime(m_currentExpoureTime);
    ui->plainTextEdit_log->appendPlainText(QString("moveToPos:(%1,%2,%3) by seppd = %4mm/s").arg(m_currentX).arg(m_currentY).arg(m_currentZ).arg(100));
    m_stageControl->moveToPos(m_currentX, m_currentY, m_currentZ, 100);
}

double DataMeasurementDialog::lineMeasure(QImage &img)
{

    int ret = -1000000;
    double x = measureSpecInfoList[m_index].startX - measureSpecInfoList[m_index].endX;
    double y = measureSpecInfoList[m_index].startY - measureSpecInfoList[m_index].endY;
    if(fabs(x) > fabs(y))
    {
        if(x > 0)
        {
            if(m_state == STATE_MOVE2START_CF || m_state == STATE_MOVE2START_TFT)
            {
                m_measurementTypt = RIGHT;
            }
            else
            {
                m_measurementTypt = LEFT;
            }
        }
        else
        {
            if(m_state == STATE_MOVE2START_CF || m_state == STATE_MOVE2START_TFT)
            {
                m_measurementTypt = LEFT;
            }
            else
            {
                m_measurementTypt = RIGHT;
            }
        }
    }
    else
    {
        if(y > 0)
        {
            if(m_state == STATE_MOVE2START_CF || m_state == STATE_MOVE2START_TFT)
            {
                m_measurementTypt = BOTTOM;
            }
            else
            {
                m_measurementTypt = TOP;
            }
        }
        else
        {
            if(m_state == STATE_MOVE2START_CF || m_state == STATE_MOVE2START_TFT)
            {
                m_measurementTypt = TOP;
            }
            else
            {
                m_measurementTypt = BOTTOM;
            }
        }
    }
    cv::Mat m_cvimage = QImage2cvMat(img);
    if(m_cvimage.empty())
    {
        return -1;
    }
    cv::Mat grayImage;//临时变量和目标图的定义
    cv::cvtColor(m_cvimage, grayImage, cv::COLOR_BGR2GRAY);

    double *pixSumPro, *pixSum;
    int dataLength;
    if(m_measurementTypt == LEFT || m_measurementTypt == RIGHT)
    {
        dataLength = grayImage.cols;
    }
    else
    {
        dataLength = grayImage.rows;
    }
    qDebug() << "dataLength = " << dataLength;
    pixSumPro = new double[dataLength];
    pixSum = new double[dataLength];
    for(int k = 0; k < dataLength; k++)
    {
        pixSumPro[k] = 0;
    }

    for (int j = 0; j < grayImage.rows; j++)
    {
        const uchar* current = grayImage.ptr<const uchar>(j); // current row
        for (int i = 0; i < grayImage.cols; i++)
        {
            if(m_measurementTypt == LEFT || m_measurementTypt == RIGHT)
            {
                pixSumPro[i] += current[i];
            }
            else
            {
                pixSumPro[j] += current[i];
            }
        }
    }

    pixSum[0] = pixSumPro[0] * 3;
    pixSum[dataLength - 1] = pixSumPro[dataLength - 1] * 3;
    for(int k = 1; k < dataLength - 1; k++)
    {
        pixSum[k] = (pixSumPro[k - 1] + pixSumPro[k] + pixSumPro[k + 1]);
    }

    double m_max = gsl_stats_max(pixSum, 1, dataLength);
    double m_min = gsl_stats_min(pixSum, 1, dataLength);
    double t = m_min + 0.1 * (m_max - m_min);
//    double t = gsl_stats_mean(pixSum, 1, dataLength);
    //qDebug() << "t = " << t;
//    if(m_state == STATE_MOVE2START_CF || m_state == STATE_MOVE2END_CF)//CF面
//    {
//        t = m_min + 0.2 * (m_max - m_min);
//    }
    qDebug() << "max = " << m_max;
    qDebug() << "min = " << m_min;
    qDebug() << "t = " << t;
    qDebug() << "max-min=" << (m_max - m_min) / dataLength;
    if(m_max - m_min < 40)
    {
        return ret;
    }
    if(m_measurementTypt == LEFT || m_measurementTypt == TOP)
    {
        for(int k = 0; k < dataLength - 1; k++)
        {
            if(pixSum[k] <= t && t <= pixSum[k + 1])
            {
                qDebug() << "pixSum[k] = " << pixSum[k] << "k = " << k;
                ret = k;
                k = dataLength;
            }
        }
    }
    else
    {
        for(int k = dataLength - 1; k > 0; k--)
        {
            if(pixSum[k] <= t && t <= pixSum[k - 1])
            {
                qDebug() << "pixSum[k] = " << pixSum[k] << "k = " << k;
                ret = k;
                k = 0;
            }
        }
    }

    if(ret < 0) return ret;

    qDebug() << "draw line";
    if(m_measurementTypt == LEFT || m_measurementTypt == RIGHT)
    {
        cv::line( m_cvimage, cv::Point(ret, 0), cv::Point(ret, m_cvimage.rows), cv::Scalar(0,255,0), 5);
    }
    else
    {
//        qDebug() << "m_cvimage.cols" << m_cvimage.cols;
        cv::line( m_cvimage, cv::Point(0, ret), cv::Point(m_cvimage.cols, ret), cv::Scalar(0,255,0), 5);
    }

    qDebug() << "add tab";
    QLabel* tab = new QLabel(ui->tabWidget_pic);
    ui->tabWidget_pic->addTab(tab, QString::fromLocal8Bit("%1").arg(m_index + 1)); //将图表加入tabWidget当中，并设置标题
    QVBoxLayout* verticalLayout = new QVBoxLayout(tab);
    verticalLayout->addWidget(tab);
    tab->setGeometry(0, 0, 390, 280);
    tab->setPixmap(QPixmap::fromImage(cvMat2QImage(m_cvimage)).scaled(tab->size()));
    ui->tabWidget_pic->setCurrentWidget(tab);
    delete[] pixSum;
    delete[] pixSumPro;
    return m_currentScale * ret / 1000;
}

void DataMeasurementDialog::measure()
{
    double x = fabs(measureSpecInfoList[m_index].startX - measureSpecInfoList[m_index].endX);
    double y = fabs(measureSpecInfoList[m_index].startY - measureSpecInfoList[m_index].endY);
    double result = 0;
    if(x > y)
    {
        result = fabs(measureSpecInfoList[m_index].startX + m_currentStartLine - m_currentEndLine - measureSpecInfoList[m_index].endX);
    }
    else
    {
        result = fabs(measureSpecInfoList[m_index].startY + m_currentStartLine - m_currentEndLine - measureSpecInfoList[m_index].endY);
    }
    if(m_state == STATE_MOVE2END_CF)
    {
        m_measureData_CF.push_back(QString::number(result));
    }
    if(m_state == STATE_MOVE2END_TFT)
    {
        m_measureData_TFT.push_back(QString::number(result));
    }
    ui->plainTextEdit_log->appendPlainText(QString("measure result:%1").arg(result));
    showData(result);
}

void DataMeasurementDialog::showData(double length)
{
    int SpecNumber = ui->lineEdit_SpecNumber->text().toInt();
    QList<MeasureSpecInfo> info;
    QList<QString> dateTime;
    QList<QStringList> data;
    m_sqlite->readMeasureSpec(info);
    m_sqlite->readMeasureData(dateTime, data, info.size(), CpkLength - 1);
    double Cpk = 0;
    if(data.size() > 0)
    {
        CpkData[0] = length;
        for(int i = 0; i < data.size(); i++)
        {
            CpkData[i + 1] = data[i].at(SpecNumber - 1).toDouble();
        }
        double mean = gsl_stats_mean(CpkData, 1, MIN(data.size() + 1, CpkLength));
        double sigma = gsl_stats_sd(CpkData, 1,  MIN(data.size() + 1, CpkLength));//standard deviation
        Cpk = MIN(fabs(mean - info[SpecNumber - 1].USL), fabs(mean - info[SpecNumber - 1].LSL)) / (3 * sigma);
        //qDebug() << "Cpk = " << Cpk;

    }

    ui->lineEdit_Length->setText(QString::number(length));
    int row = ui->tableWidget_Data->rowCount();      //获取当前数据行数
    ui->tableWidget_Data->insertRow(row);            //在末尾插入一行setHorizontalHeaderLabels
    QTableWidgetItem* verticalHeaderItem = new QTableWidgetItem(QString::fromLocal8Bit("测点%1").arg(ui->lineEdit_SpecNumber->text()));
    ui->tableWidget_Data->setVerticalHeaderItem(row, verticalHeaderItem);
    ui->tableWidget_Data->setItem(row,0,new  QTableWidgetItem(QString::number(length)));//length
    ui->tableWidget_Data->setItem(row,1,new  QTableWidgetItem(QString::number(Cpk)));//cpk
    ui->tableWidget_Data->setItem(row,2,new  QTableWidgetItem(ui->lineEdit_LSL->text()));//lsl
    ui->tableWidget_Data->setItem(row,3,new  QTableWidgetItem(ui->lineEdit_LCL->text()));//lcl
    ui->tableWidget_Data->setItem(row,4,new  QTableWidgetItem(ui->lineEdit_CL->text()));//cl
    ui->tableWidget_Data->setItem(row,5,new  QTableWidgetItem(ui->lineEdit_UCL->text()));//ucl
    ui->tableWidget_Data->setItem(row,6,new  QTableWidgetItem(ui->lineEdit_USL->text()));//usl
}

void DataMeasurementDialog::Save()
{
    ui->pushButton_Save->setEnabled(false);
    if(m_measureData_CF.size() < measureSpecInfoList_CF.size() || m_measureData_TFT.size() < measureSpecInfoList_TFT.size())
    {
        QMessageBox::warning(this, QString::fromLocal8Bit("警告"), QString::fromLocal8Bit("测量未完成，请重新测量！"));
        return;
    }
    //
    if(m_sqlite->writeData2Sqlite("", measureSpecInfoList_CF.size() + m_measureData_TFT.size(), m_measureData_CF + m_measureData_TFT))
    {
        addChart2TabWidget();
    }
    else
    {
        QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("保存失败！"));
    }
    return;
    //
    if(QMessageBox::question(this, QString::fromLocal8Bit("询问"), QString::fromLocal8Bit("是否保存数据到数据库？")) == QMessageBox::Yes)
    {
        if(m_sqlite->writeData2Sqlite("", measureSpecInfoList_CF.size() + m_measureData_TFT.size(), m_measureData_CF + m_measureData_TFT))
        {
            QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("保存成功！"));
            addChart2TabWidget();
        }
        else
        {
            QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("保存失败！"));
        }
    }
}

//"delete from book where name = ?"
//"update Book set price = ? where name =?"
